import pandas as pd
import influxdb 
import dateutil.parser as dtparser
import datetime
from Config.myConfig import InfluxdbServer,logger
########################################################################
class InfluxdbUtility(object):
    """influxdb辅助工具"""
    #----------------------------------------------------------------------
    @classmethod 
    def getAllMeausrements(self,database:str,connet=InfluxdbServer):
        client = influxdb.DataFrameClient(host=connet['host'], port=connet['port'], username=connet['username'], password=['password'], database=database)
        tables=client.get_list_measurements()
        tables=pd.DataFrame(tables)
        tables=list(tables['name'])
        return tables
    #----------------------------------------------------------------------
    @classmethod 
    def getDataFromInfluxdb(self,code,date,database,columns=[],connet=InfluxdbServer):
        client = influxdb.DataFrameClient(host=connet['host'], port=connet['port'], username=connet['username'], password=['password'], database=database)
        measure=code
        b = dtparser.parse(str(date))+ datetime.timedelta(hours=0)
        e = dtparser.parse(str(date)) + datetime.timedelta(hours=24)
        colstr=''
        if len(columns)>0:
            for col in columns:
                colstr=colstr+f""" "{col}", """
            colstr=colstr[:-2]
        else:
            colstr='*'
        query=f""" select {colstr} from "{database}"."autogen"."{measure}" where time >= {int(b.timestamp() * 1000 * 1000 * 1000)} and time < {int(e.timestamp() * 1000 * 1000* 1000)} """
        result=client.query(query)
        if result!={}:
            data=pd.DataFrame(result[measure])
            
        else:
            data=pd.DataFrame()
        return data
    #----------------------------------------------------------------------
    @classmethod 
    def saveDataFrameDataToInfluxdb(self,data:pd.DataFrame,database:str,measurement:str,tag:dict,connet=InfluxdbServer):
        client = influxdb.DataFrameClient(host=connet['host'], port=connet['port'], username=connet['username'], password=connet['password'], database='')
        dbs = client.get_list_database()
        if ({'name':database} in dbs)==False:
            client.create_database(database)
        success=False
        myerror=''
        #讲data中的nan转化为none
        #data=data.where(pd.notnull(data),None)
        for i in range(10):
            try:
                client.write_points(dataframe=data,
                        database=database,
                        measurement=measurement,
                        tags=tag,
                        field_columns=list(data.columns),
                        protocol='line',
                        batch_size=10000)
                success=True
                break
            except Exception as excp:
                myerror=excp
                pass
        if success==False:
            logger.error(f'save data to influxdb {measurement} in {tag} error! {myerror}')
        pass
    #----------------------------------------------------------------------
    @classmethod 
    def saveDataFrameDataToInfluxdbWithClient(self,client,data:pd.DataFrame,database:str,measurement:str,tag:dict,connet=InfluxdbServer):
        
        dbs = client.get_list_database()
        if ({'name':database} in dbs)==False:
            client.create_database(database)
        success=False
        myerror=''
        #讲data中的nan转化为none
        #data=data.where(pd.notnull(data),None)
        for i in range(10):
            try:
                client.write_points(dataframe=data,
                        database=database,
                        measurement=measurement,
                        tags=tag,
                        field_columns=list(data.columns),
                        protocol='line',
                        batch_size=10000)
                success=True
                break
            except Exception as excp:
                myerror=excp
                pass
        if success==False:
            logger.error(f'save data to influxdb {measurement} in {tag} error! {myerror}')
        pass

    @classmethod
    def savedailyDataFrameDataToInfluxdbWithClient(self, client, data: pd.DataFrame, database: str, measure: str):

        dbs = client.get_list_database()
        if ({'name': database} in dbs) == False:
            client.create_database(database)
        success_flag = False
        for i in range(10):
            try:
                client.write_points(dataframe=data, database=database, measurement=measure, tag_columns=['code'],
                                         protocol='line', batch_size=1000)
                success_flag = True
                break
            except Exception as excp:
                error_msg = excp
        if not success_flag:
            print(error_msg)
        else:
            error_msg = 'No error occurred...'
            print('data saved!')
        return error_msg
########################################################################
